﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using NSDecisionTree.Tools;

namespace NSDecisionTree.Classes
{
    class CSV_File : IDisposable
    {
        #region private

        string filename;
        string delimiter;
        int rowcount;
        int items;
        DecisionTable completeDecisionObject;
        private bool disposed = false;

        #endregion

        #region public

        public string Filename
        {
            get { return filename; }
            set { filename = value; }
        }
        public string Delimiter
        {
            get { return delimiter; }
            set { delimiter = value; }
        }
        public int Rowcount
        {
            get { return rowcount; }
        }
        public int Items
        {
            get { return items; }
        }
        internal DecisionTable CompleteDecisionObject
        {
            get { return completeDecisionObject; }
        }

        #endregion

        #region ctor

        private CSV_File() : this("", ";")
        {
        }

        public CSV_File(string Filename) : this(Filename, ";")
        {
        }

        public CSV_File(string Filename, string Delimiter) : this(Filename, Delimiter, -1)
        {
        }

        public CSV_File(string Filename, string Delimiter, int ResultatField)
        {
            if (String.IsNullOrEmpty(Filename))
            {
                clear();
            }
            else
            {
                filename = Filename;
                delimiter = Delimiter;
                if (!(LoadFile(ResultatField)))
                {
                    clear();
                }
            }
        }

        #endregion

        #region methods

        private bool LoadFile(int ResultatField)
        {
            bool retVal = false;

            try
            {
                // Complete File
                String[] fileContent = File.ReadAllLines(filename);
                // # Items in 1st row
                int fileItems = fileContent[0].Count(test => test.ToString() == delimiter);
                // complete 1st row
                string caption = fileContent[0];
                // Items of first row seperated
                List<string> decisions = new List<string>();
                DecisionTable ds;

                if (ResultatField < 0 || ResultatField > fileItems)
                {
                    List<string> captions = caption.ToSeperatedStringList(delimiter);

                    ds = new DecisionTable(captions);

                    for (int i = 1; i < fileContent.Length; i++)
                    {
                        List<string> tempList = fileContent[i].ToSeperatedStringList(delimiter);
                        ds.AddRowItem(tempList);
                        string tempResultat = tempList.Last();

                        if (!decisions.Contains(tempResultat))
                            decisions.Add(tempResultat);
                    }

                }
                else
                {
                    List<string> captions = caption.ToSeperatedStringList(delimiter);
                    string resultat = captions.ElementAt(ResultatField);
                    captions.RemoveAt(ResultatField);
                    captions.Add(resultat);

                    ds = new DecisionTable(captions);

                    for (int i = 1; i < fileContent.Length; i++)
                    {
                        List<string> temp = fileContent[i].ToSeperatedStringList(delimiter);
                        string tempResultat = temp.ElementAt(ResultatField);
                        
                        if (!decisions.Contains(tempResultat))
                            decisions.Add(tempResultat);

                        temp.RemoveAt(ResultatField);
                        temp.Add(tempResultat);
                        ds.AddRowItem(temp);
                    }
                }

                completeDecisionObject = ds;
                completeDecisionObject.AddResultItems(decisions);
                retVal = true;
            }
            catch (Exception ex)
            {
                ex.ToString();
            }

            return retVal;
        }

        private void clear()
        {
            filename = String.Empty;
            delimiter = Delimiter;
            rowcount = 0;
            items = 0;
            completeDecisionObject = null;
        }

        #endregion

        #region dispose

        //Implement IDisposable.
        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        protected virtual void Dispose(bool disposing)
        {
            if (!disposed)
            {
                if (disposing)
                {
                    // Free other state (managed objects).
                }
                clear();
                disposed = true;
            }
        }

        // Use C# destructor syntax for finalization code.
        ~CSV_File()
        {
            Dispose (false);
        }

        #endregion
    }
}
